package com.tompai.file.service;

import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import com.tompai.file.mapper.UserMapper;
import com.tompai.file.pojo.User;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import com.tompai.file.exception.FileStorageException;
import com.tompai.file.exception.MyFileNotFoundException;
import com.tompai.file.property.FileStorageProperties;

@Slf4j
@Service
public class FileStorageService {

    private final Path fileStorageLocation;

    @Autowired
    private UserMapper userMapper;

    /**
     * 自动注入
     */
    @Autowired
    public FileStorageService(FileStorageProperties fileStorageProperties) {
        this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir()).toAbsolutePath().normalize();

        try {
            Files.createDirectories(this.fileStorageLocation);
        } catch (Exception ex) {
            throw new FileStorageException("Could not create the directory where the uploaded files will be stored.",
                    ex);
        }
    }

    /*
    //上述代码可以改为这种形式
    private final UserMapper userMapper;

    @Autowired
    public FileStorageService(FileStorageProperties fileStorageProperties, UserMapper userMapper) {
        this.fileStorageLocation = Paths.get(fileStorageProperties.getUploadDir()).toAbsolutePath().normalize();

        try {
            Files.createDirectories(this.fileStorageLocation);
        } catch (Exception ex) {
            throw new FileStorageException("Could not create the directory where the uploaded files will be stored.",
                    ex);
        }
        this.userMapper = userMapper;
    }
     */

    /**
     * 上传文件，保存到yml文件设置的保存地址，如果是excel文件将其数据读入数据库
     *
     * @param file 文件
     * @return 文件名
     */
    public String storeFile(MultipartFile file) {
        // Normalize file name
        String fileName = StringUtils.cleanPath(Objects.requireNonNull(file.getOriginalFilename()));
        log.info("fileName " + fileName);

        try {
            // Check if the file's name contains invalid characters
            if (fileName.contains("..")) {
                throw new FileStorageException("Sorry! Filename contains invalid path sequence " + fileName);
            }

            // Copy file to the target location (Replacing existing file with the same name)
            //文件绝对路径 如：C:\Apps\文件1.doc
            Path targetLocation = this.fileStorageLocation.resolve(fileName);
            log.info("targetLocation " + targetLocation);
            //复制文件到yml设置的存储路径下
            Files.copy(file.getInputStream(), targetLocation, StandardCopyOption.REPLACE_EXISTING);

            if (!fileName.matches("^.+\\.(?i)(xls)$") && !fileName.matches("^.+\\.(?i)(xlsx)$")) {
                log.info("上传文件格式不正确 ");
            } else {
                //如果是excel文件则读取文件数据并存入数据库中
                log.info("上传文件格式正确 ");
                //读取Excel中所有行和列，都用列表表示
                ExcelReader reader1 = ExcelUtil.getReader(targetLocation.toString());
                List<List<Object>> readAll1 = reader1.read();
                log.info("readAll1 " + readAll1);

                //读取为Map列表，默认第一行为标题行，Map中的key为标题，value为标题对应的单元格值。
                ExcelReader reader2 = ExcelUtil.getReader(targetLocation.toString());
                List<Map<String, Object>> readAll2 = reader2.readAll();
                log.info("readAll2 " + readAll2);

                log.info("------------------- ");
                //读取为Bean列表，Bean中的字段名为标题，字段值为标题对应的单元格值。
                ExcelReader reader3 = ExcelUtil.getReader(targetLocation.toString());
                //User类为与数据库表相同的pojo类
                List<User> all3 = reader3.readAll(User.class);
                log.info("all3 " + all3.toString());

                //插入数据库
                for (User user : all3) {
                    int insert = userMapper.insert(user);
                    log.info("insert " + insert);
                }
            }

            return fileName;
        } catch (IOException ex) {
            throw new FileStorageException("Could not store file " + fileName + ". Please try again!", ex);
        }
    }

    /**
     * 下载文件
     *
     * @param fileName 文件名
     * @return 资源
     */
    public Resource loadFileAsResource(String fileName) {
        try {
            Path filePath = this.fileStorageLocation.resolve(fileName).normalize();
            Resource resource = new UrlResource(filePath.toUri());
            if (resource.exists()) {
                return resource;
            } else {
                throw new MyFileNotFoundException("File not found " + fileName);
            }
        } catch (MalformedURLException ex) {
            throw new MyFileNotFoundException("File not found " + fileName, ex);
        }
    }
}
